/**************************************************************************//**
 * @item     CosyOS-II Kernel
 * @file     sv_task.h
 * @brief    任务服务
 * @detail   仅在任务中调用并执行。
 * @author   迟凯峰
 * @version  V3.1.0
 * @date     2024.11.11
 ******************************************************************************/

#ifndef __SV_TASK_H
#define __SV_TASK_H

void       su_enter_critical    (void);
void       su_exit_critical     (void);
void      *su_return_voidptr    (void *p);
void       su_enter_critical_one(void);
void       su_exit_critical_one (void);
void       su_exit_critical_psv (void);
void       su_task_schedule     (void);
s_ecode_t  su_startup_task      (s_taskhand_tsp hhand, s_voidvoid_tfp entry, s_u8_t status);
s_ecode_t  su_suspend_task      (s_tasknode_tsp htask);
s_ecode_t  su_resume_task       (s_tasknode_tsp htask);
s_ecode_t  su_resume_suspend    (s_tasknode_tsp htask);
s_ecode_t  su_delete_task       (s_tasknode_tsp htask);
s_ecode_t  su_set_taskpri       (s_tasknode_tsp htask, s_u8_t pri);
s_ecode_t  su_set_block         (s_tasknode_tsp htask, s_delay_t tick);
s_ecode_t  su_clear_block       (s_tasknode_tsp htask);
void       su_delay             (s_delay_t tick);
s_bool_t   su_take_mutex        (s_mutex_tsp hmut, s_delay_t tick);
void       su_back_mutex        (s_mutex_tsp hmut);
s_bool_t   su_wait_binary       (s_binary_tsp hbin, s_delay_t tick);
s_bool_t   su_take_binary       (s_binary_tsp hbin, s_delay_t tick);
void       su_give_binary       (s_binary_tsp hbin);
s_bool_t   su_take_semaphore    (s_semaph_tsp hsem, s_delay_t tick);
void       su_give_semaphore    (s_semaph_tsp hsem);
s_bool_t   su_recv_taskmsg      (m_taskmsg_t _STATIC_MEM_ *flag, s_delay_t tick);
m_fetion_t su_recv_fetion       (s_tionbox_tsp htbox, s_delay_t tick);
void      *su_recv_mail         (s_mailbox_tsp hmbox, s_delay_t tick);
void       su_send_mail         (s_mailbox_tsp hmbox, void *mail);
void      *su_recv_msg          (s_queue_tsp hque, s_delay_t tick);
s_ecode_t  su_send_msg          (s_queue_tsp hque, void *msg);
s_bool_t   su_query_group       (void _STATIC_MEM_ *hgrp, s_u8_t size);
s_bool_t   su_wait_group        (void _STATIC_MEM_ *hgrp, s_u8_t size, s_delay_t tick);
s_bool_t   su_init_mempool      (s_thrmem_tsp hmem, size_t size);
void _MALLOC_MEM_ *su_talloc    (s_thrmem_tsp hmem, size_t size);
void _MALLOC_MEM_ *su_xalloc    (void _MALLOC_MEM_ *p);

/**
 @addtogroup 任务服务
 @{
 */

/*
 * 操作任务
 */

/** 启动任务 */
#define sUSV_StartTask(hhand, entry, status) \
( \
	(m_boolvoid_tf(su_enter_critical_one))() || true ? su_startup_task((s_taskhand_tsp)hhand, entry, !status ? OS_STATUS_READY : OS_STATUS_SUSPENDED) : OS_ECODE_NOERROR \
)

/** 挂起任务 */
#define sUSV_SuspendTask(htask) \
( \
	(m_boolvoid_tf(su_enter_critical))() || true ? su_suspend_task(htask) : OS_ECODE_NOERROR \
)

/** 恢复任务 */
#define sUSV_ResumeTask(htask) \
( \
	(m_boolvoid_tf(su_enter_critical))() || true ? su_resume_task(htask) : OS_ECODE_NOERROR \
)

/** 恢复指定任务并挂起自身任务 */
#define sUSV_ResumeSuspend(htask) \
( \
	(m_boolvoid_tf(su_enter_critical))() || true ? su_resume_suspend(htask) : OS_ECODE_NOERROR \
)

/** 删除任务 */
#define sUSV_DeleteTask(htask) \
( \
	(m_boolvoid_tf(su_enter_critical))() || true ? su_delete_task(htask) : OS_ECODE_NOERROR \
)

/** 设置任务优先级 */
#define sUSV_SetTaskPri(htask, pri) \
( \
	(m_boolvoid_tf(su_enter_critical))() || true ? su_set_taskpri(htask, pri) : OS_ECODE_NOERROR \
)

/** 设置阻塞（时间）*/
#define sUSV_SetBlock(htask, tick) \
( \
	(m_boolvoid_tf(su_enter_critical))() || true ? su_set_block(htask, tick) : OS_ECODE_NOERROR \
)

/** 清除阻塞（状态）*/
#define sUSV_ClearBlock(htask) \
( \
	(m_boolvoid_tf(su_enter_critical))() || true ? su_clear_block(htask) : OS_ECODE_NOERROR \
)

/** 自身任务延时 */
#define sUSV_Delay(tick) \
do{ \
	uEnterCritical; \
	su_delay(tick); \
}while(false)

/** 任务调度 */
#define sUSV_TaskSchedule  su_task_schedule()



/*
 * 定时
 */

/** 定时中断 */
#define sUSV_TimInt(tmid, tick) \
do{ \
	uEnterCritical; \
	s_timint_handle[tmid]->timer = s_timint_handle[tmid]->reload = tick; \
	uExitCritical; \
}while(false)

/** 定时查询 */
#define sUSV_TimQry(tmid, tick) \
do{ \
	uEnterCritical; \
	s_timqry_handle[tmid]->timer = s_timqry_handle[tmid]->reload = tick; \
	uExitCritical; \
}while(false)



/*
 * 互斥信号量
 */

/** 获取互斥信号量 */
#define sUSV_TakeMut(mut, tick) \
( \
	(m_boolvoid_tf(su_enter_critical_one))() || true ? su_take_mutex(&mut, tick) : false \
)

/** 归还互斥信号量 */
#define sUSV_BackMut(mut) \
do{ \
	uEnterCritical; \
	su_back_mutex(&mut); \
}while(false)



/*
 * 二值信号量
 */

/** 等待二值信号量 */
#define sUSV_WaitBin(bin, tick) \
( \
	(m_boolvoid_tf(su_enter_critical_one))() || true ? su_wait_binary(&bin, tick) : false \
)

/** 获取二值信号量 */
#define sUSV_TakeBin(bin, tick) \
( \
	(m_boolvoid_tf(su_enter_critical_one))() || true ? su_take_binary(&bin, tick) : false \
)

/** 给予二值信号量 */
#define sUSV_GiveBin(bin) \
do{ \
	uEnterCritical; \
	su_give_binary(&bin); \
}while(false)



/*
 * 计数信号量
 */

/** 获取计数信号量 */
#define sUSV_TakeSem(sem, tick) \
( \
	(m_boolvoid_tf(su_enter_critical_one))() || true ? su_take_semaphore(&sem, tick) : false \
)

/** 给予计数信号量 */
#define sUSV_GiveSem(sem) \
do{ \
	uEnterCritical; \
	su_give_semaphore(&sem); \
}while(false)



/*
 * 私信
 */

/** 接收私信 */
#define sUSV_RecvTaskMsg(tick) \
( \
	(m_boolvoid_tf(su_enter_critical_one))() || true \
	? su_recv_taskmsg(&m0_, tick) \
		? s_memcpy(&m0 + 1, &m0_ + 1, MCUCFG_TASKMSG_SIZE) || true \
			? (m_boolvoid_tf(su_exit_critical_one))() || true \
			: (m_boolvoid_tf(su_exit_critical_one))() || true \
		: false \
	: false \
)

/** 发送私信 */
#define sUSV_SendTaskMsg(task) \
	uEnterCritical; \
	s_sign_send_taskmsg = true; \
	MCUCFG_TASKMSG_PSP; \
	s_switch_taskmsg(u_taskhandle_##task); \
	task(MCUCFG_TASKMSG_VAL, 



/*
 * 飞信
 */

/** 接收飞信 */
#define sUSV_RecvFetion(tbox, tick) \
( \
	(m_boolvoid_tf(su_enter_critical_one))() || true ? su_recv_fetion(&tbox, tick) : false \
)

/** 发送飞信 */
#define sUSV_SendFetion(tbox, tion) \
do{ \
	uEnterCritical; \
	tbox.fetion = tion; \
	s_switch_notnull(tbox.htask); \
	uExitCritical; \
}while(false)



/*
 * 邮箱
 */

/** 接收邮件 */
#define sUSV_RecvMail(mbox, tick) \
( \
	(m_boolvoid_tf(su_enter_critical_one))() || true ? su_recv_mail(&mbox, tick) : OS_NULL \
)

/** 发送邮件 */
#define sUSV_SendMail(mbox, mail) \
do{ \
	uEnterCritical; \
	su_send_mail(&mbox, mail); \
}while(false)



/*
 * 消息队列
 */

/** 接收消息 */
#define sUSV_RecvMsg(que, tick) \
( \
	(m_boolvoid_tf(su_enter_critical_one))() || true ? su_recv_msg((s_queue_tsp)&que, tick) : OS_NULL \
)

/** 发送消息 */
#define sUSV_SendMsg(que, msg) \
( \
	(m_boolvoid_tf(su_enter_critical))() || true ? su_send_msg((s_queue_tsp)&que, msg) : OS_ECODE_NOERROR \
)



/*
 * 事件标志组
 */

/** 查询标志组 */
#define sUSV_QueryFlagGroup(group) \
( \
	(m_boolvoid_tf(su_enter_critical))() || true ? su_query_group((void *)&group, sizeof(group)) : false \
)

/** 等待标志组 */
#define sUSV_WaitFlagGroup(group, tick) \
( \
	(m_boolvoid_tf(su_enter_critical_one))() || true ? su_wait_group((void *)&group, sizeof(group), tick) : false \
)

/** 清除标志组 */
#define sUSV_ClearFlagGroup(group) \
do{ \
	uEnterCritical; \
	sizeof(group) == 1 ? *(s_u8_t  *)&group = false : MCUCFG_TERNARYMASK \
	sizeof(group) == 2 ? *(s_u16_t *)&group = false : MCUCFG_TERNARYMASK \
	sizeof(group) == 4 ? *(s_u32_t *)&group = false : false; \
	uExitCritical; \
}while(false)

/** 写标志位 */
#define sUSV_WriteFlagBit(group, bit, value) \
do{ \
	uEnterCritical; \
	group.bit = value; \
	uExitCritical; \
}while(false)



/*
 * 软件RTC
 */

/** 获取时间 */
#define sUSV_GetTime(t) \
( \
	(m_boolvoid_tf(su_enter_critical))() || true ? su_return_voidptr(s_memcpy(t, s_rtc[0], sizeof(s_rtc[0]))) : OS_NULL \
)

/** 设置时间 */
#define sUSV_SetTime(t) \
do{ \
	uEnterCritical; \
	s_memcpy(s_rtc[0], t, sizeof(s_rtc[0])); \
	uUpdateCopy(s_memcpy(s_rtc[1], s_rtc[0], sizeof(s_rtc[0]))); \
	uExitCritical; \
}while(false)



/*
 * 进程内存
 */

/** malloc */
#define sUSV_Malloc(size) \
( \
	(m_boolvoid_tf(su_enter_critical))() || true ? su_xalloc((void _MALLOC_MEM_ *)s_malloc(size)) : OS_NULL \
)

/** calloc */
#define sUSV_Calloc(nmemb, size) \
( \
	(m_boolvoid_tf(su_enter_critical))() || true ? su_xalloc((void _MALLOC_MEM_ *)s_calloc(nmemb, size)) : OS_NULL \
)

/** realloc */
#define sUSV_Realloc(p, size) \
( \
	(m_boolvoid_tf(su_enter_critical))() || true ? su_xalloc((void _MALLOC_MEM_ *)s_realloc(p, size)) : OS_NULL \
)

/** free */
#define sUSV_Free(p) \
do{ \
	uEnterCritical; \
	s_free(p); \
	uExitCritical; \
}while(false)



/*
 * 线程内存
 */

/** 初始化线程内存池 */
#define sUSV_InitMempool(size) \
( \
	(m_boolvoid_tf(su_enter_critical))() || true ? su_init_mempool(&u_thrmem, size) : false \
)

/** 线程内存分配 */
#define sUSV_Talloc(size) \
( \
	(m_boolvoid_tf(su_enter_critical))() || true ? su_xalloc(su_talloc(&u_thrmem, size)) : OS_NULL \
)

/** 释放线程内存池 */
#define sUSV_FreeMempool \
do{ \
	sUSV_Free(u_thrmem.head); \
	u_thrmem.head = u_thrmem.move = OS_NULL; \
}while(false)

/** @} */

#endif
